package cn.ante.ymcc.service.impl;

import cn.ante.ymcc.domain.KillActivity;
import cn.ante.ymcc.domain.KillCourse;
import cn.ante.ymcc.mapper.KillActivityMapper;
import cn.ante.ymcc.service.IKillActivityService;
import cn.ante.ymcc.service.IKillCourseService;
import cn.ante.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.errorprone.annotations.Var;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Nai
 * @since 2022-08-23
 */
@Service
@Transactional
public class KillActivityServiceImpl extends ServiceImpl<KillActivityMapper, KillActivity> implements IKillActivityService {

    @Autowired
    private IKillActivityService killActivityService;

    @Autowired
    private IKillCourseService killCourseService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public void publish(Long killActivityId) {
        AssertUtil.isNotEmpty(killActivityId.toString());
        // 查询活动的发布状态是否是未发布
        KillActivity killActivity = killActivityService.selectById(killActivityId);
        AssertUtil.isNotNull(killActivity,"活动不存在");

        boolean isWait = killActivity.getPublishStatus() == KillActivity.STATES_WAIT_PUBLISH;
        AssertUtil.isTrue(isWait,"活动状态不合法");

        // 当前的时间是小于活动时间的
        boolean before = new Date().before(killActivity.getEndTime());
        AssertUtil.isTrue(before,"活动已结束");

        // 根据活动id得到秒杀课程集合
        Wrapper<KillCourse> wrapper = new EntityWrapper<>();
        wrapper.eq("activity_id",killActivityId);
        List<KillCourse> killCourses = killCourseService.selectList(wrapper);

        // 设置活动的状态和开始时间
        killActivity.setPublishStatus(KillActivity.STATES_OK_PUBLISH);
        killActivity.setPublishTime(new Date());

        killCourses.stream().forEach(killCourse -> {
            // 设置秒杀课程的信号量
            String semaphoreKey = killActivity.getId() + ":" + killCourse.getId();
            RSemaphore semaphore = redissonClient.getSemaphore(semaphoreKey);
            boolean setPermits = semaphore.trySetPermits(killCourse.getKillCount());
            if (setPermits){
                // 将活动和活动中的秒杀课程一起存入redis中
            redisTemplate.opsForHash().put(
                    "Activity" + killActivityId,
                    killCourse.getId().toString(),
                    killCourse
            );
            // 设置秒杀课程的状态和开始时间
            killCourse.setPublishStatus(killActivity.getPublishStatus());
            killCourse.setPublishTime(killActivity.getPublishTime());
            killCourseService.updateById(killCourse);
            }else{
                // 返回兜底数据
            }
        });
        updateById(killActivity);

    }
}
